package com.sduept.nwld.dataserver.service.equipment.assessment.rest;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.sduept.bigdata.equipment.assessment.dto.QuestionTypeDTO;
import com.sduept.bigdata.equipment.assessment.dto.RequirementRiskNumDTO;
import com.sduept.bigdata.equipment.assessment.dto.RiskLevelDTO;
import com.sduept.bigdata.equipment.assessment.dto.SubstationSectionDTO;
import com.sduept.bigdata.equipment.assessment.enums.ItemTypeEnum;
import com.sduept.bigdata.equipment.assessment.exception.ParameterException;
import com.sduept.bigdata.equipment.assessment.model.hiddendanger.track.RectificationPlan;
import com.sduept.bigdata.equipment.assessment.model.inspection.InspectionItem;
import com.sduept.bigdata.equipment.assessment.model.inspection.InspectionQuestionEquipment;
import com.sduept.bigdata.equipment.assessment.model.inspection.InspectionStation;
import com.sduept.bigdata.equipment.assessment.service.InspectionStationService;
import com.sduept.bigdata.equipment.assessment.service.InspectionStatisticalAnalysisService;

import lombok.extern.slf4j.Slf4j;

/**
 * 精益化评价统计分析
 * @author huangyu
 * @Date 2019年9月23日
 */
@Slf4j
@RestController
@RequestMapping("/assessment")
public class AssessmentStatisticsService {
	
	@Autowired
	private InspectionStatisticalAnalysisService service;
	@Autowired
	private InspectionStationService stationService;
	
	/**
	 * 根据计划id，获取每个得分区间内的变电站个数
	 * @param planId
	 * @return 
	 */

	@GetMapping("/getStationCountInScoreRange/{planId}")
	public List<ScoreSectionCountDTO> getInspectionStationCountInScoreRange(@PathVariable("planId")String planId) {
		SubstationSectionDTO substationSectionDTO = service.getSubstationSection(planId);
		
		List<ScoreSectionCountDTO> list = new ArrayList<ScoreSectionCountDTO>();
		Map<Float, List<InspectionStation>> map = substationSectionDTO.getMap();
		float score;
		for (int i=0; i<100; i=i+10) {
			ScoreSectionCountDTO dto = new ScoreSectionCountDTO();
			dto.setMin(i);
			dto.setMax(i+10);
			score = i+10;
			List<InspectionStation> stations = map.get(score);
			if(null == stations) {
				dto.setCount(0);
			} else {
				dto.setCount(stations.size());
			}
			list.add(dto);
		}
		return list;
	}
	
	/**
	 * 获取某计划下的所有问题设备的风险等级分布
	 * @param planId
	 * @return 
	 */

	@GetMapping("/getDangerLevelDistribute/{planId}")
	public List<DangerLevelCountDTO> getDangerLevelDistribute1(@PathVariable("planId")String planId) {
		RiskLevelDTO riskLevelDTO = service.getRiskLevelByPlanId(planId);
		Map<String, List<InspectionQuestionEquipment>> map = riskLevelDTO.getRiskLevelMap();
		List<DangerLevelCountDTO> list = new ArrayList<DangerLevelCountDTO>();
		for (Entry<String, List<InspectionQuestionEquipment>> entry : map.entrySet()) {
			DangerLevelCountDTO dto = new DangerLevelCountDTO();
			List<InspectionQuestionEquipment> qes = entry.getValue();
			String riskLevel = entry.getKey();
			int count = 0;
			for (InspectionQuestionEquipment qe : qes) {
				count += qe.getQuestionAmount();
			}
			dto.setCount(count);
			dto.setDangerLevel(riskLevel);
			list.add(dto);
		}
		return list;
	}
	
	/**
	 * 获取某个计划下的类型为ItemTypeEnum.INSPECTIONREQUIREMENT的评分项的扣分次数
	 * @param planId
	 * @return
	 */

	@GetMapping("/getInspectionItemCount/{planId}")
	public List<InspectionItemCountDTO> getInspectionItemCountByDangerLevel(@PathVariable("planId")String planId) {
		
		RequirementRiskNumDTO requirementRiskDTO = service.getRequirementRiskByPlanId(planId);
		Map<String, Integer> itemMap = requirementRiskDTO.getRequirementRiskMap();
		List<InspectionItemCountDTO> list = new ArrayList<InspectionItemCountDTO>();
		for (String itemName : itemMap.keySet()) {
			InspectionItemCountDTO dto = new InspectionItemCountDTO();
			dto.setItemName(itemName);
			dto.setCount(itemMap.get(itemName));
			list.add(dto);
		}
		sort(list);
		return list;
	}


	@GetMapping("/getStationComplateRatio/{planId}")
	public List<InspectionStationComplateDTO> getStationComplateRatioByPlanId(@PathVariable("planId")String planId) {
		List<InspectionStationComplateDTO> dtos = new ArrayList<InspectionStationComplateDTO>();
		try {
			List<InspectionStation> stationsAll = stationService.findByInspectionPlanWithExpertAndItems(planId);
			for (InspectionStation station : stationsAll) {
				InspectionStationComplateDTO stationDto = new InspectionStationComplateDTO();
				stationDto.setStationName(station.getStationName());
				List<InspectionItem> all = station.getInspectionItems();
				// 仅获取检查标准类型的项目
				List<InspectionItem> itemsTotal = findInspectionItemByType(all, ItemTypeEnum.INSPECTIONCRITERION);
				int finish = 0;
				int unfinish = 0;
				for (InspectionItem item : itemsTotal) {
					if(0 == item.getStatus()) {
						unfinish++;
					} else if (1 == item.getStatus()) {
						finish++;
					}
				}
				stationDto.setItemsNumAll(itemsTotal.size());
				stationDto.setItemsNumFinished(finish);
				stationDto.setItemsNumUnfinish(unfinish);
				String ratio = getRatio(finish, itemsTotal.size());
				stationDto.setFinishRatio(ratio);
				dtos.add(stationDto);
			}
		} catch (ParameterException e) {
			e.printStackTrace();
			log.info("获取计划的检查站出错");
		}
		sortStationDTO(dtos);
		return dtos;
	}
	
	/**
	 * 根据整改计划，统计不同问题类型的整改计划完成情况
	 */

	@GetMapping("/getRectificationPlanCompletion/{planId}")
	public List<ProblemCompletionDTO> getRectificationPlanCompletion(@PathVariable("planId")String planId) {
		List<ProblemCompletionDTO> result = new ArrayList<ProblemCompletionDTO>();
		QuestionTypeDTO questionTypeDTO = service.getQuestionTypeCountByInspectionPlanId(planId);
		Map<String, List<RectificationPlan>> map = questionTypeDTO.getQuestionTypeMap();
		
		List<RectificationPlan> values = null;
		for (Entry<String, List<RectificationPlan>> entry : map.entrySet()) {
			ProblemCompletionDTO dto = new ProblemCompletionDTO();
			dto.setType(entry.getKey());
			dto.setFinishCount(0);
			dto.setUnnfinishCount(0);
			values = entry.getValue();
			for (RectificationPlan rp : values) {
				if(0 == rp.getStatus()) {
					dto.setUnnfinishCount(dto.getUnnfinishCount()+1);
				} else {
					dto.setFinishCount(dto.getFinishCount()+1);
				}
			}
			String ratio = getRatio(dto.getFinishCount(), dto.getUnnfinishCount()+dto.getFinishCount());
			dto.setRatio(ratio);
			result.add(dto);
		}
		sortByRatio(result);
		return result;
	}
	
	/**
	 * 根据变电站的完成率排序
	 * @param dtos
	 */
	private void sortStationDTO(List<InspectionStationComplateDTO> dtos) {
		Collections.sort(dtos, new Comparator<InspectionStationComplateDTO>() {
			@Override
			public int compare(InspectionStationComplateDTO o1, InspectionStationComplateDTO o2) {
				if(Float.parseFloat(o1.getFinishRatio()) > Float.parseFloat(o2.getFinishRatio())) {
					return -1;
				} else if (Float.parseFloat(o1.getFinishRatio()) == Float.parseFloat(o2.getFinishRatio())) {
					return 0;
				} else {
					return 1;
				}
			}
		});
	}
	
	
	/**
	 * 将ProblemCompletionDTO按ratio从高到低排序
	 * @param List<ProblemCompletionDTO>
	 */
	private void sortByRatio(List<ProblemCompletionDTO> dtos) {
		Collections.sort(dtos,new Comparator<ProblemCompletionDTO> () {
			
			@Override
			public int compare(ProblemCompletionDTO o1, ProblemCompletionDTO o2) {
				float f1 = Float.parseFloat(o1.getRatio());
				float f2 = Float.parseFloat(o2.getRatio());
				if(f2>f1) {
					return 1;
				} else if (f2<f1) {
					return -1;
				} else {
					return 0;
				}
			}
		});
	}
	/**
	 * 将InspectionItemCountDTO按count从高到低排序
	 * @param List<InspectionItemCountDTO>
	 */
	private void sort(List<InspectionItemCountDTO> dtos) {
		Collections.sort(dtos,new Comparator<InspectionItemCountDTO> () {
			
			@Override
			public int compare(InspectionItemCountDTO o1, InspectionItemCountDTO o2) {
				return o2.getCount()-o1.getCount();
			}
			
		});
	}
	
	/**
	 * 根据分子、分母获取比率，保留两位小数
	 * @param numerator
	 * @param denominator
	 * @return 
	 */
	private String getRatio(int numerator,int denominator) {
		String ratio;
		DecimalFormat df = new DecimalFormat("#0.00");
		if(0 == denominator) {
			ratio = "0";
		} else {
			double result = numerator*100/denominator;
			ratio = df.format(result);
		}
		return ratio;
	}
	
	/**
	 * 从List<InspectionItem>中筛选出指定类型的记录
	 * @param allItems
	 * @return 
	 */
	private List<InspectionItem> findInspectionItemByType(List<InspectionItem> allItems, ItemTypeEnum type) {
		List<InspectionItem> result = new ArrayList<InspectionItem>();
		for (InspectionItem item : allItems) {
			if(item.getItemType() == type) {
				result.add(item);
			}
		}
		return result;
	}
	
	/**
	 * 用于展示变电站的评价项目信息的DTO（此处只统计类型为INSPECTIONCRITERION("检查标准", "INSPECTIONCRITERION")的评价项目）
	 * @author huangyu
	 * @Date 2019年10月11日
	 */
	public class InspectionStationComplateDTO {
		/**
		 * 检查站名称
		 */
		private String stationName;
		/**
		 * 已完成评价项数量
		 */
		private int itemsNumFinished;
		/**
		 * 未完成评价项数量
		 */
		private int itemsNumUnfinish;
		/**
		 * 所有评价项数量
		 */
		private int itemsNumAll;
		/**
		 * 完成率
		 */
		private String finishRatio;
		public String getStationName() {
			return stationName;
		}
		public int getItemsNumFinished() {
			return itemsNumFinished;
		}
		public int getItemsNumUnfinish() {
			return itemsNumUnfinish;
		}
		public int getItemsNumAll() {
			return itemsNumAll;
		}
		public String getFinishRatio() {
			return finishRatio;
		}
		public void setStationName(String stationName) {
			this.stationName = stationName;
		}
		public void setItemsNumFinished(int itemsNumFinished) {
			this.itemsNumFinished = itemsNumFinished;
		}
		public void setItemsNumUnfinish(int itemsNumUnfinish) {
			this.itemsNumUnfinish = itemsNumUnfinish;
		}
		public void setItemsNumAll(int itemsNumAll) {
			this.itemsNumAll = itemsNumAll;
		}
		public void setFinishRatio(String finishRatio) {
			this.finishRatio = finishRatio;
		}
	}
	
	/**
	 * 用于展示评分项的扣分次数（此处仅统计类型为ItemTypeEnum.INSPECTIONREQUIREMENT的评分项）
	 * @author huangyu
	 * @Date 2019年9月20日
	 */
	public class InspectionItemCountDTO {
		/**
		 * 评价项内容
		 */
		private String itemName;
		/**
		 * 在该评价项扣分的变电站个数
		 */
		private int count;
		
		public String getItemName() {
			return itemName;
		}

		public void setItemName(String itemName) {
			this.itemName = itemName;
		}

		public int getCount() {
			return count;
		}

		public void setCount(int count) {
			this.count = count;
		}
	}
	
	
	/**
	 * 用于展示风险等级分布图封装的DTO
	 * @author huangyu
	 */
	public class DangerLevelCountDTO {
		/**
		 * 风险等级
		 */
		private String dangerLevel;
		/**
		 * 问题设备个数
		 */
		private int count;

		public String getDangerLevel() {
			return dangerLevel;
		}

		public void setDangerLevel(String dangerLevel) {
			this.dangerLevel = dangerLevel;
		}

		public int getCount() {
			return count;
		}

		public void setCount(int count) {
			this.count = count;
		}
		
	}
		
	/**
	 * 用于展示分数分布饼形图封装的DTO
	 * @author huangyu
	 * @Date 2019年9月19日
	 */
	public class ScoreSectionCountDTO {
		/**
		 * 分数范围 高值
		 */
		private int max;
		/**
		 * 分数范围 低值
		 */
		private int min;
		/**
		 * 在该分值范围内的变电站个数
		 */
		private int count;

		public int getMax() {
			return max;
		}

		public int getMin() {
			return min;
		}

		public int getCount() {
			return count;
		}

		public void setMax(int max) {
			this.max = max;
		}

		public void setMin(int min) {
			this.min = min;
		}

		public void setCount(int count) {
			this.count = count;
		}
		
	}
	
	

	class ProblemCompletionDTO {
		/**
		 * 问题类型
		 */
		private String type;
		/**
		 * 已完成数量
		 */
		private int finishCount;
		/**
		 * 未完成数量
		 */
		private int unnfinishCount;
		/**
		 * 完成率
		 */
		private String ratio;
		
		public String getType() {
			return type;
		}
		public int getFinishCount() {
			return finishCount;
		}
		public int getUnnfinishCount() {
			return unnfinishCount;
		}
		public String getRatio() {
			return ratio;
		}
		public void setType(String type) {
			this.type = type;
		}
		public void setFinishCount(int finishCount) {
			this.finishCount = finishCount;
		}
		public void setUnnfinishCount(int unnfinishCount) {
			this.unnfinishCount = unnfinishCount;
		}
		public void setRatio(String ratio) {
			this.ratio = ratio;
		}
	}
}
